package com.wxscrmplus.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.wxscrmplus.common.core.domain.entity.SysUser;
import com.wxscrmplus.common.utils.StringUtils;
import com.wxscrmplus.common.core.page.TableDataInfo;
import com.wxscrmplus.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wxscrmplus.customer.domain.CusType;
import com.wxscrmplus.customer.domain.feat.CustomerFeat;
import com.wxscrmplus.customer.domain.vo.CusTypeVo;
import com.wxscrmplus.customer.domain.vo.CustomerVo;
import com.wxscrmplus.customer.mapper.CusTypeMapper;
import com.wxscrmplus.customer.mapper.CustomerMapper;
import com.wxscrmplus.customer.service.ICustomerService;
import com.wxscrmplus.statistics.service.ICustomerStatsService;
import com.wxscrmplus.system.mapper.SysUserMapper;
import com.wxscrmplus.wxcp.factory.WxCpServiceFactory;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpMessageService;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.springframework.stereotype.Service;
import com.wxscrmplus.customer.domain.bo.CusMaintainBo;
import com.wxscrmplus.customer.domain.vo.CusMaintainVo;
import com.wxscrmplus.customer.domain.CusMaintain;
import com.wxscrmplus.customer.mapper.CusMaintainMapper;
import com.wxscrmplus.customer.service.ICusMaintainService;

import java.math.BigDecimal;
import java.util.*;

/**
 * 客户维护Service业务层处理
 *
 * @author 王永超
 * @date 2023-03-26
 */
@RequiredArgsConstructor
@Service
public class CusMaintainServiceImpl extends WxCpServiceFactory implements ICusMaintainService {

    private final CusMaintainMapper baseMapper;
    private final SysUserMapper userMapper;
    private final ICustomerService customerService;
    private final CustomerMapper customerMapper;
    private final CusTypeMapper typeMapper;
    private final ICustomerStatsService customerStatsService;


    /**
     * 查询客户维护
     */
    @Override
    public CusMaintainVo queryById(Long maintainId) {
        CusMaintainVo cusMaintainVo = baseMapper.selectVoById(maintainId);
        cusMaintainVo.setUserNickName(userMapper.findNickNameById(cusMaintainVo.getUserId()));
        return cusMaintainVo;
    }

    /**
     * 查询客户维护列表
     */
    @Override
    public TableDataInfo<CusMaintainVo> queryPageList(CusMaintainBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CusMaintain> lqw = buildQueryWrapper(bo);
        Page<CusMaintainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for (CusMaintainVo record : result.getRecords()) {
            record.setUserNickName(userMapper.findNickNameById(record.getUserId()));
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询客户维护列表
     */
    @Override
    public List<CusMaintainVo> queryList(CusMaintainBo bo) {
        LambdaQueryWrapper<CusMaintain> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<CusMaintain> buildQueryWrapper(CusMaintainBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CusMaintain> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getCustomerId() != null, CusMaintain::getCustomerId, bo.getCustomerId());
        lqw.eq(StringUtils.isNotBlank(bo.getRemark()), CusMaintain::getRemark, bo.getRemark());
        lqw.eq(StringUtils.isNotBlank(bo.getMaintainWay()), CusMaintain::getMaintainWay, bo.getMaintainWay());
        lqw.in(CollectionUtil.isNotEmpty(bo.getDataRangeUserIds()), CusMaintain::getUserId, bo.getDataRangeUserIds());
        lqw.orderByDesc(CusMaintain::getMaintainId);
        return lqw;
    }

    /**
     * 新增客户维护
     */
    @Override
    public Boolean insertByBo(CusMaintainBo bo) {
        CusMaintain add = BeanUtil.toBean(bo, CusMaintain.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
// b3ce893c83248069c4f016e4fde8c447
        if (flag) {
            bo.setMaintainId(add.getMaintainId());
        }
        customerStatsService.refreshCostsByCustomerIds(add.getCustomerId());
        this.customerCostFcw(add);
        return flag;
    }

    /**
     * 修改客户维护
     */
    @Override
    public Boolean updateByBo(CusMaintainBo bo) {
        CusMaintain update = BeanUtil.toBean(bo, CusMaintain.class);
        validEntityBeforeSave(update);
        customerStatsService.refreshCostsByCustomerIds(update.getCustomerId());
        this.customerCostFcw(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CusMaintain entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除客户维护
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for (CusMaintainVo cusMaintainVo : baseMapper.selectVoBatchIds(ids)) {
            customerStatsService.refreshCostsByCustomerIds(cusMaintainVo.getCustomerId());
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    /**
     * 维护成本（负利润）超支预警
     */
    public void customerCostFcw(CusMaintain maintain) {
        CustomerVo customerVo = customerMapper.selectVoById(maintain.getCustomerId());
        CustomerFeat customerFeat = BeanUtil.toBean(customerVo, CustomerFeat.class);
        customerFeat.calculatProfit();
        customerVo.setProfit(customerFeat.getProfit());
        BigDecimal profit = customerVo.getProfit().multiply(new BigDecimal("100"));
        if (profit.intValue() < 0) {
            //利润小于0
            CusTypeVo cusTypeVo = typeMapper.selectVoById(customerVo.getCusTypeId());
            if (cusTypeVo.getFcwType().equals(CusType.FcwTypeFieldEnums.FULIRUNCHAOCHUFAZHI.getValue())) {
                //预警
                BigDecimal limitLose = cusTypeVo.getLimitLose().multiply(new BigDecimal("100"));
                if (profit.abs().intValue() > limitLose.intValue()) {
                    //已经超支
                    SysUser sysUser = userMapper.selectById(maintain.getUserId());
                    WxCpMessageService messageService = getMessageService();
                    WxCpMessage wxCpMessage = new WxCpMessage();
                    wxCpMessage.setMsgType("text");
                    wxCpMessage.setContent("负利润已经达到阀值预警" + "\n" +
                        "客户：" + customerVo.getName() + "\n" +
                        "利润：" + profit.divide(new BigDecimal("100")) + "\n" +
                        "超支：" + profit.abs().divide(new BigDecimal("100")).subtract(limitLose.divide(new BigDecimal("100"))) + "\n" +
                        "最近维护成员：" + sysUser.getNickName()
                    );
                    List<Long> receiveUserId = cusTypeVo.getReceiveUserId();
                    for (Long userId : receiveUserId) {
                        SysUser user = userMapper.selectById(userId);
                        wxCpMessage.setToUser(user.getUserName());
                        try {
                            messageService.send(wxCpMessage);
                        } catch (WxErrorException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
    }

}
